package controller

import (
	"StrayAnimals/internal/service"
	"StrayAnimals/pkg/errorx"
	"StrayAnimals/pkg/utils"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/google/uuid"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"mime/multipart"
	"strings"
)

// UpdateBaseMsg 更新用户基本信息
func UpdateBaseMsg(c *gin.Context) {
	// 定义请求体结构
	var userInput struct {
		ID       string `json:"id"`       // 用户ID
		Username string `json:"username"` // 用户名
		Phone    string `json:"phone"`    // 电话
		Gender   string `json:"gender"`   // 性别
		Birthday string `json:"birthday"` // 生日
		Avatar   string `json:"avatar"`   // 头像
	}

	// 解析请求体
	if err := c.ShouldBindJSON(&userInput); err != nil {
		c.JSON(400, gin.H{
			"code":    401,
			"message": "参数错误；" + err.Error(),
		})
		return
	}

	// 验证 ID 是否为空
	if userInput.ID == "" {
		c.JSON(400, gin.H{
			"code":    402,
			"message": "用户 ID 不能为空",
		})
		return
	}

	// 根据 ID 查询用户是否存在
	user, err := service.GetUserByID(userInput.ID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(400, gin.H{
				"code":    403,
				"message": "用户不存在；" + err.Error(),
			})
		} else {
			c.JSON(500, gin.H{
				"code":    501,
				"message": "系统错误，请稍后再试；" + err.Error(),
			})
		}
		return
	}

	// 更新用户的基本信息
	if userInput.Username != "" {
		user.Username = userInput.Username
	}
	if userInput.Phone != "" {
		user.Phone = userInput.Phone
	}
	if userInput.Gender != "" {
		user.Gender = userInput.Gender
	}
	if userInput.Birthday != "" {
		user.Birthday = userInput.Birthday
	}
	if userInput.Avatar != "" {
		user.Avatar = userInput.Avatar
	}

	// 将更新后的用户信息保存到数据库
	if err := service.UpdateUser(user); err != nil {
		c.JSON(500, gin.H{
			"code":    501,
			"message": "系统错误，更新失败，请稍后再试；" + err.Error(),
		})
		return
	}

	// 将头像保存到历史头像数据库
	if err := service.SaveHistoryAvatar(userInput.ID, userInput.Avatar); err != nil {
		c.JSON(500, gin.H{
			"code":    501,
			"message": "系统错误，无法保存头像到历史头像库，请稍后再试；" + err.Error(),
		})
		return
	}

	// 返回成功响应
	c.JSON(200, gin.H{
		"code":    200,
		"message": "基本信息更新成功",
	})
}

// UploadAvatar 上传头像到图床
func UploadAvatar(c *gin.Context) {
	// 定义请求体结构
	var userInput struct {
		File *multipart.FileHeader `form:"file"` // 头像文件
	}

	// 解析请求体（支持 form-data）
	if err := c.ShouldBindWith(&userInput, binding.FormMultipart); err != nil {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "参数错误；" + err.Error(),
		})
		return
	}

	// 打开文件
	src, err := userInput.File.Open()
	if err != nil {
		c.JSON(500, gin.H{
			"code":    500,
			"message": "无法打开文件；" + err.Error(),
		})
		return
	}
	defer func(src multipart.File) {
		err := src.Close()
		if err != nil {
			zap.L().Error("Failed to close file", zap.Error(err))
		}
	}(src)

	// 获取文件名和扩展名
	originalFilename := strings.TrimSpace(userInput.File.Filename)
	suffix := originalFilename[strings.LastIndex(originalFilename, "."):]
	prefix := uuid.New().String()
	fileName := prefix + suffix

	// 调用工具函数上传文件
	url, err := service.UploadFileToRemote(src, fileName)
	if err != nil {
		c.JSON(500, gin.H{
			"code":    500,
			"message": "上传文件失败；" + err.Error(),
		})
		return
	}

	// 返回成功响应
	if strings.HasPrefix(url, "http") {
		c.JSON(200, gin.H{
			"code":    200,
			"message": url,
		})
	} else {
		c.JSON(500, gin.H{
			"code":    500,
			"message": "上传失败",
		})
	}
}

// UpdatePassword 更新用户密码
func UpdatePassword(c *gin.Context) {
	var userInput struct {
		ID       string `json:"id"`
		Password string `json:"password"`
		Captcha  string `json:"captcha"`
	}

	// 解析请求体
	if err := c.ShouldBindJSON(&userInput); err != nil {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "参数错误；" + err.Error(),
		})
		return
	}

	// 验证 ID 是否为空
	if userInput.ID == "" {
		c.JSON(400, gin.H{
			"code":    402,
			"message": "用户 ID 不能为空",
		})
		return
	}

	// 根据 ID 查询用户是否存在
	user, err := service.GetUserByID(userInput.ID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(400, gin.H{
				"code":    403,
				"message": "用户不存在；" + err.Error(),
			})
		} else {
			c.JSON(500, gin.H{
				"code":    501,
				"message": "系统错误，请稍后再试；" + err.Error(),
			})
		}
		return
	}

	// 查询验证码并校验有效性
	storedCaptcha, err := service.CheckCaptcha(user.Email)
	if err != nil {
		if errors.Is(err, errorx.ErrCaptchaNotFound) {
			c.JSON(400, gin.H{
				"code":    405,
				"message": "未获取验证码/验证码已过期，请获取验证码以验证身份",
			})
		} else {
			c.JSON(500, gin.H{
				"code":    501,
				"message": "系统错误，更改密码失败，请稍后再试；" + err.Error(),
			})
		}
		return
	}

	// 校验验证码
	if userInput.Captcha != storedCaptcha {
		c.JSON(400, gin.H{
			"code":    405,
			"message": "验证码错误，请检查验证码",
		})
		return
	}

	// 加密密码
	hashedPassword, err := service.EncryptPassword(userInput.Password)
	if err != nil {
		c.JSON(500, gin.H{
			"code":    501,
			"message": "系统错误，更改密码失败，请稍后再试；" + err.Error(),
		})
		return
	}

	// 更新密码
	user.Password = string(hashedPassword)

	// 将更新后的密码保存到数据库
	if err := service.UpdateUser(user); err != nil {
		c.JSON(500, gin.H{
			"code":    501,
			"message": "系统错误，更改密码失败，请稍后再试；" + err.Error(),
		})
		return
	}

	c.JSON(200, gin.H{
		"code":    200,
		"message": "密码更改成功",
	})
}

// UpdateEmail 更新用户邮箱
func UpdateEmail(c *gin.Context) {
	var userInput struct {
		ID      string `json:"id"`
		Email   string `json:"email"`
		Captcha string `json:"captcha"`
	}

	// 解析请求体
	if err := c.ShouldBindJSON(&userInput); err != nil {
		c.JSON(400, gin.H{
			"code":    401,
			"message": "参数错误；" + err.Error(),
		})
		return
	}

	// 根据ID查询用户信息
	user, err := service.GetUserByID(userInput.ID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(400, gin.H{
				"code":    403,
				"message": "用户不存在；" + err.Error(),
			})
		} else {
			c.JSON(500, gin.H{
				"code":    501,
				"message": "系统错误，请稍后再试；" + err.Error(),
			})
		}
		return
	}

	// 查询验证码并校验有效性
	storedCaptcha, err := service.CheckCaptcha(userInput.Email)
	if err != nil {
		if errors.Is(err, errorx.ErrCaptchaNotFound) {
			c.JSON(400, gin.H{
				"code":    405,
				"message": "未获取验证码/验证码已过期，请获取验证码以验证身份",
			})
		} else {
			c.JSON(500, gin.H{
				"code":    501,
				"message": "系统错误，更改邮箱失败，请稍后再试；" + err.Error(),
			})
		}
		return
	}

	// 校验验证码
	if userInput.Captcha != storedCaptcha {
		c.JSON(400, gin.H{
			"code":    405,
			"message": "验证码错误，请检查验证码",
		})
		return
	}

	// 检查邮箱是否为空
	if userInput.Email == "" {
		c.JSON(400, gin.H{
			"code":    402,
			"message": "新邮箱不能为空",
		})
		return
	}

	// 验证邮箱格式
	if !utils.IsValidEmail(userInput.Email) {
		c.JSON(400, gin.H{
			"code":    409,
			"message": "新邮箱格式不正确",
		})
		return
	}

	user.Email = userInput.Email

	// 将更新后的邮箱保存到数据库
	if err := service.UpdateUser(user); err != nil {
		c.JSON(500, gin.H{
			"code":    501,
			"message": "系统错误，更改邮箱失败，请稍后再试；" + err.Error(),
		})
		return
	}

	c.JSON(200, gin.H{
		"code":    200,
		"message": "邮箱更改成功",
	})
}
